/*-----------------------------------------------------------------------
|                            FILE DESCRIPTION                           |
-----------------------------------------------------------------------*/
/*----------------------------------------------------------------------
  - File name     : list.h
  - Author        : liuzhihua
  - Update date   : 2024.1.27
  -	File Function : list lib for C
  - Source Code   : https://gitee.com/Createtree/elist
  - UTF-8 Encoding
-----------------------------------------------------------------------*/
/*-----------------------------------------------------------------------
|                               UPDATE NOTE                             |
-----------------------------------------------------------------------*/
/**
  * Update note:
  * ------------   ---------------   ----------------------------------
  *     Date            Author                      Note
  * ------------   ---------------   ----------------------------------
  *  2023.03.15       liuzhihua                 Create file      
  *  2023.04.02       liuzhihua                 Update v1.1        
  *  2024.01.27       liuzhihua                 Update v1.2
***/

#ifndef LIST_H_
#define LIST_H_

#ifdef  __cplusplus
    extern "C" {
#endif
/*-----------------------------------------------------------------------
|                                NCLUDES                                |
-----------------------------------------------------------------------*/
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
/*-----------------------------------------------------------------------
|                                DEFINES                                |
-----------------------------------------------------------------------*/
#define _listAssert(x) assert(x)
#define _listMalloc(x) malloc(x)
#define _listFree(x) free(x)
typedef struct list_Node_Structure node_t;
typedef struct list_Structure list_t;

struct list_Node_Structure
{
  void *data;
  node_t *prior; 
  node_t *next;
};
struct list_Structure
{
  node_t *head, *tail;
  uint32_t len;
};

#define _LIST_STATIC_INLINE   static inline
#define _LIST_USE_INLINE      inline
#define _LIST_USE_INLINE_EX    //inline
/*-----------------------------------------------------------------------
|                                  API                                  |
-----------------------------------------------------------------------*/
/* Create and add */

list_t *listCreate(void);
list_t *listStaticCreate(list_t *plist);
node_t *listCreateNode(void *data);
node_t *listStaticCreateNode(node_t *pnode, void *data);


/* Node operate */

_LIST_USE_INLINE_EX node_t  *NodeGetNext(node_t *node);
_LIST_USE_INLINE_EX node_t  *NodeToNext(node_t **node);
_LIST_USE_INLINE_EX node_t  *NodeGetPrior(node_t *node);
_LIST_USE_INLINE_EX node_t  *NodeToPrior(node_t **node);
_LIST_USE_INLINE_EX void     NodeWrite(node_t *node, void *data);
_LIST_USE_INLINE_EX void    *NodeRead(node_t *node);
_LIST_USE_INLINE_EX uint32_t listGetLen(list_t *root);
_LIST_USE_INLINE_EX node_t  *listGetHead(list_t *root);
_LIST_USE_INLINE_EX node_t  *listGetTail(list_t *root);
_LIST_USE_INLINE_EX node_t  *listRemoveNodeAt(list_t *root, uint32_t index);
node_t                      *listGetNode(list_t *root, uint32_t index);
uint32_t                     listRemoveNode(list_t *root, node_t *pnode);
uint32_t                     listInsertNodeAt(list_t *root, node_t *node, uint32_t pos);


/* Data operate */

uint32_t                     listPush(list_t *root, uint32_t pos, void *data);
void                        *listPop(list_t *root, uint32_t index);
uint32_t                     listArrayToList(list_t *root, void *arr, uint32_t sizeofType, uint32_t len);
node_t                      *listSearchData(list_t *root, void *data);
uint32_t                     listSearchNode(list_t *root, node_t *pnode);
_LIST_USE_INLINE_EX void     listWrite(list_t *root, uint32_t index, void *data);
_LIST_USE_INLINE_EX void    *listRead(list_t *root, uint32_t index);


/* destory and free*/

void                         listDestroy(list_t **root);
_LIST_USE_INLINE_EX uint32_t listDeleteNode(list_t *root, node_t *pnode);
uint32_t                     listDeleteNodeAt(list_t *root, uint32_t index);
_LIST_USE_INLINE_EX void     listDataFree(node_t *node, void data_free(void *));
void                         listDatasFree(list_t *root, void data_free(void *));

#define listPushh(root, data)   listPush((root), 0, data)
#define listPusht(root, data)   listPush((root), listGetLen(root), data)
#define listPoph(root)          listPop((root), 0)
#define listPopt(root)          listPop((root), listGetLen(root)-1)

#define listIteratorh(_plist_, _index_) for(_index_ = 0; _index_ < listGetLen(_plist_); _index_++)
#define listIteratort(_plist_, _index_) for(_index_ = listGetLen(_plist_) - 1U; (uint32_t)_index_ < (_plist_)->len; _index_--)

#ifdef __cplusplus
	}
#endif
#endif
